package com.mt.roll.core.utils;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * ip地址解析工具类
 * </p>
 *
 * @author Mr.ZhangShi
 * @date 2019/1/22
 * @since 1.0
 */
public class IPAddressParseUtil {

    /**
     * 百度地图AK
     */
    private final static String BAIDU_DI_TU_AK = "nbnrq7DlVZTXffRVPEUeKpiqzqelCkjB";

    /**
     * 获取真实ip地址
     *
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (!checkIP(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (!checkIP(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (!checkIP(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (!checkIP(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (!checkIP(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (!checkIP(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    private static boolean checkIP(String ip) {
        if (ip == null || ip.length() == 0 || "unkown".equalsIgnoreCase(ip)
                || ip.split(".").length != 4) {
            return false;
        }
        return true;
    }

    /**
     * 根据request获取地理位置信息
     *
     * @param request
     * @return 返回地址信息对象
     * @throws JSONException
     * @throws IOException
     */
    public static Address getAddress(HttpServletRequest request) throws JSONException, IOException {
        return getAddress(HttpUtil.getClientIP(request));
    }

    public static String getProvince(String IP) throws JSONException, IOException {
        //这里调用百度的ip定位api服务 详见 http://api.map.baidu.com/lbsapi/cloud/ip-location-api.htm
        JSONObject json = readJsonFromUrl("http://api.map.baidu.com/location/ip?ak=" + BAIDU_DI_TU_AK + "&ip=" + IP);
        String status = json.get("status").toString();
        if (!"0".equals(status)) {
            return null;
        }
        return ((JSONObject) ((JSONObject) json.get("content")).get("address_detail")).get("province").toString();
    }

    /**
     * 根据ip地址获取地理位置信息
     *
     * @param ip
     * @return 返回地址信息对象
     * @throws JSONException
     * @throws IOException
     */
    public static Address getAddress(String ip) throws JSONException, IOException {
        JSONObject json = readJsonFromUrl("http://ip.taobao.com/service/getIpInfo.php?ip=" + ip);

        /* 获取到的json对象：
         *        {
         *          "code":0,
         *          "data":{
         *              "ip":"36.27.93.185","country":"中国","area":"","region":"浙江","city":"杭州","county":"XX","isp":"电信","country_id":"CN","area_id":"","region_id":"330000","city_id":"330100","county_id":"xx","isp_id":"100017"
         *              }
         *         }
         */
        if (json == null) {
            return null;
        }
        // code
        String status = json.get("code").toString();
        if (!"0".equals(status)) {
            return null;
        }
        // 获取json对象里的data对象
        return json.getObject("data", Address.class);
    }

    /**
     * 地址id校验
     *
     * @param addressId
     * @return
     */
    public static boolean addressIdVerify(String addressId) {
        if (StringUtils.isEmpty(addressId)) {
            return false;
        }
        String regex = "\\d{6}";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(addressId);
        return matcher.find();
    }

    private static String readAll(Reader rd) throws IOException {
        StringBuilder sb = new StringBuilder();
        int cp;
        while ((cp = rd.read()) != -1) {
            sb.append((char) cp);
        }
        return sb.toString();
    }

    public static JSONObject readJsonFromUrl(String url) throws IOException, JSONException {
        InputStream is = null;
        try {
            is = new URL(url).openStream();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
            String jsonText = readAll(rd);
            JSONObject json = JSONObject.parseObject(jsonText);
            return json;
        } finally {
            //关闭输入流
            if (is != null) {
                is.close();
            }
        }
    }

    @Data
    public static class Address {

        /**
         * 真实ip
         */
        private String ip;

        /**
         * 国家
         */
        private String country;

        /**
         * 区域
         */
        private String area;

        /**
         * 地区、省
         */
        private String region;

        /**
         * 地市
         */
        private String city;

        /**
         * 县
         */
        private String county;

        private String isp;

        private String country_id;

        private String area_id;

        private String region_id;

        private String city_id;

        private String county_id;

        private String isp_id;
    }
}
